﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NullObjectPattern
{
    /// <summary>
    /// Hard Null for Car
    /// </summary>
    class CarHardNull : IAssignable
    {
        /// <summary>
        /// Constructor of the CarHardNull class, initialization of a 'm_IsNull' field
        /// </summary>
        /// <param name="hNull"></param>
        public CarHardNull(bool hNull)
        {
            m_IsNull = hNull;
        }

        #region Properties

        public static CarHardNull Null
        {
            get
            {
                return new CarHardNull(true);
            }
        }

        public bool IsNull
        {
            get
            {
                return m_IsNull;
            }
        }

        /// <summary>
        /// Max speed of the car
        /// </summary>
        public int MaxSpeed
        {
            get { return m_MaxSpeed; }
            set
            {
                if (m_IsNull)
                    throw new InvalidOperationException();

                m_MaxSpeed = value;
            }
        }

        /// <summary>
        /// Engine capacity of the car
        /// </summary>
        public double EngineCapacity
        {
            get { return m_EngineCapacity; }
            set
            {
                if (m_IsNull)
                    throw new InvalidOperationException();

                m_EngineCapacity = value;
            }
        }

        /// <summary>
        /// Name of the car
        /// </summary>
        public string Name
        {
            get { return m_Name; }
            set
            {
                if (m_IsNull)
                    throw new InvalidOperationException();

                m_Name = value;
            }
        }

        /// <summary>
        /// Number of the car
        /// </summary>
        public int Number
        {
            get { return m_Number; }
            set
            {
                if (m_IsNull)
                    throw new InvalidOperationException();

                m_Number = value;
            }
        }

        #endregion

        #region IAssignable implementation

        public void AssignTo(object obj)
        {
            if (m_IsNull)
                throw new InvalidOperationException("Operation is not possible");

            if (obj == null)
                throw new ArgumentNullException();

            if (obj is CarSoftNull)
            {
                CarSoftNull car = obj as CarSoftNull;

                car.Name = this.Name;
                car.Number = this.Number;
                car.MaxSpeed = this.MaxSpeed;
                car.EngineCapacity = this.EngineCapacity;

                return;
            }

            throw new NotSupportedException();
        }

        #endregion

        #region Private fields

        private int m_Number = default(int);
        private string m_Name = default(string);
        private double m_EngineCapacity = default(double);
        private int m_MaxSpeed = default(int);
        private bool m_IsNull = false;

        #endregion

    }
}
